#ifndef JZ_RESULT_H_
#define JZ_RESULT_H_

#include <optional>
#include <QString>

class JZError
{
public:
	JZError();
	JZError(const QString& error);

	QString error;
};

template<class T>
class JZResult
{
public:
	JZResult(T &&t)
	{
		m_value = t;
	}

	JZResult(const JZError &error)
	{
		m_error = error;
	}

	bool isOK() const
	{
		return m_value.has_value();
	}

	const JZError& error() const
	{
		return m_error;
	}

	const QString &errorString() const
	{
		return m_error.error;
	}

	T&& takeValue()
	{
		return m_value.value();
	}

protected:
	std::optional<T> m_value;
	JZError m_error;
};

template<>
class JZResult<void>
{
public:
	JZResult()
	{
		m_value = true;
	}

	JZResult(const JZError& error)
	{
		m_value = false;
		m_error = error;
	}

	bool isOK() const
	{
		return m_value;
	}

	const JZError& error() const
	{
		return m_error;
	}

	const QString& errorString() const
	{
		return m_error.error;
	}

protected:
	bool m_value;
	JZError m_error;
};

#endif // !JZ_RESULT_H_
